Google workflowsで外部のAPIからデータを取得してみる

Google workflowsで外部のAPIからデータを取得してみる

Clock Icon2024.09.29

はじめに

データアナリティクス事業本部のkobayashiです。

GoogleCloudのWorkflowsではGoogleCloudのリソースの操作を各Stepで行うこともできますが、外部のAPIからデータを取得してそのレスポンスを扱うこともできます。今回は外部のAPIからデータを取得して表示してみたのでまとめます。

https://cloud.google.com/workflows/docs/http-requests?hl=ja

WorkflowsでHTTP リクエストを行う

WorkflowsではHTTPエンドポイントに対してHTTPリクエストの呼び出しを行うことができます。公式ドキュメントの冒頭には

たとえば、HTTP リクエストを介して Cloud Functions や Cloud Run などの Google Cloud サービスを呼び出すことができます。

となっていますが、GoogleCloud以外の外部HTTPエンドポイントに対してもリクエストを行うことももちろんできます。

では早速試してみます。

Workflowsで外部のHTTPエンドポイントを呼び出してみる

今回呼び出してみるHTTPエンドポイントは気象庁のエリアごとの週間天気予報を取得するAPIになります。

https://www.jma.go.jp/bosai/forecast/data/forecast/{都道府県・エリアコード}.json

このAPIで取得できるのは以下のようなJSONになります。

レスポンスのサンプル
[
  {
    "publishingOffice": "熊谷地方気象台",
    "reportDatetime": "2024-09-26T17:00:00+09:00",
    "timeSeries": [
      {
        "areas": [
          {
            "area": {
              "code": "110020",
              "name": "北部"
            },
            "weatherCodes": [
              "200",
              "203",
              "203"
            ],
            "weathers": [
              "くもり",
              "くもり 時々 雨 所により 昼前 から 夜のはじめ頃 雷を伴い 激しく 降る",
              "くもり 時々 雨"
            ],
            "winds": [
              "南東の風",
              "北西の風 後 北の風",
              "北西の風"
            ]
          },
          {
            "area": {
              "code": "110010",
              "name": "南部"
            },
            "weatherCodes": [
              "200",
              "203",
              "203"
            ],
            "weathers": [
              "くもり",
              "くもり 時々 雨 所により 昼前 から 夜のはじめ頃 雷を伴い 激しく 降る",
              "くもり 時々 雨"
            ],
            "winds": [
              "南東の風",
              "北の風 後 やや強く",
              "北の風"
            ]
          },
          {
            "area": {
              "code": "110030",
              "name": "秩父地方"
            },
            "weatherCodes": [
              "200",
              "203",
              "203"
            ],
            "weathers": [
              "くもり",
              "くもり 時々 雨 所により 昼前 から 夜のはじめ頃 雷を伴い 激しく 降る",
              "くもり 時々 雨"
            ],
            "winds": [
              "東の風 後 南西の風",
              "北の風 後 東の風",
              "西の風"
            ]
          }
        ],
        "timeDefines": [
          "2024-09-26T17:00:00+09:00",
          "2024-09-27T00:00:00+09:00",
          "2024-09-28T00:00:00+09:00"
        ]
      },
      {
        "areas": [
          {
            "area": {
              "code": "110020",
              "name": "北部"
            },
            "pops": [
              "10",
              "30",
              "70",
              "70",
              "60"
            ]
          },
          {
            "area": {
              "code": "110010",
              "name": "南部"
            },
            "pops": [
              "10",
              "30",
              "70",
              "70",
              "60"
            ]
          },
          {
            "area": {
              "code": "110030",
              "name": "秩父地方"
            },
            "pops": [
              "20",
              "30",
              "70",
              "70",
              "60"
            ]
          }
        ],
        "timeDefines": [
          "2024-09-26T18:00:00+09:00",
          "2024-09-27T00:00:00+09:00",
          "2024-09-27T06:00:00+09:00",
          "2024-09-27T12:00:00+09:00",
          "2024-09-27T18:00:00+09:00"
        ]
      },
      {
        "areas": [
          {
            "area": {
              "code": "43056",
              "name": "熊谷"
            },
            "temps": [
              "22",
              "25"
            ]
          },
          {
            "area": {
              "code": "43241",
              "name": "さいたま"
            },
            "temps": [
              "22",
              "24"
            ]
          },
          {
            "area": {
              "code": "43156",
              "name": "秩父"
            },
            "temps": [
              "20",
              "24"
            ]
          }
        ],
        "timeDefines": [
          "2024-09-27T00:00:00+09:00",
          "2024-09-27T09:00:00+09:00"
        ]
      }
    ]
  },
  {
    "precipAverage": {
      "areas": [
        {
          "area": {
            "code": "43056",
            "name": "熊谷"
          },
          "max": "45.7",
          "min": "15.5"
        }
      ]
    },
    "publishingOffice": "熊谷地方気象台",
    "reportDatetime": "2024-09-26T17:00:00+09:00",
    "tempAverage": {
      "areas": [
        {
          "area": {
            "code": "43056",
            "name": "熊谷"
          },
          "max": "24.9",
          "min": "16.9"
        }
      ]
    },
    "timeSeries": [
      {
        "areas": [
          {
            "area": {
              "code": "110000",
              "name": "埼玉県"
            },
            "pops": [
              "",
              "80",
              "50",
              "40",
              "30",
              "40",
              "50"
            ],
            "reliabilities": [
              "",
              "",
              "C",
              "B",
              "A",
              "B",
              "C"
            ],
            "weatherCodes": [
              "203",
              "203",
              "202",
              "200",
              "201",
              "200",
              "202"
            ]
          }
        ],
        "timeDefines": [
          "2024-09-27T00:00:00+09:00",
          "2024-09-28T00:00:00+09:00",
          "2024-09-29T00:00:00+09:00",
          "2024-09-30T00:00:00+09:00",
          "2024-10-01T00:00:00+09:00",
          "2024-10-02T00:00:00+09:00",
          "2024-10-03T00:00:00+09:00"
        ]
      },
      {
        "areas": [
          {
            "area": {
              "code": "43056",
              "name": "熊谷"
            },
            "tempsMax": [
              "",
              "26",
              "27",
              "29",
              "30",
              "30",
              "25"
            ],
            "tempsMaxLower": [
              "",
              "25",
              "23",
              "26",
              "27",
              "27",
              "23"
            ],
            "tempsMaxUpper": [
              "",
              "33",
              "31",
              "31",
              "33",
              "33",
              "31"
            ],
            "tempsMin": [
              "",
              "20",
              "20",
              "21",
              "21",
              "22",
              "20"
            ],
            "tempsMinLower": [
              "",
              "19",
              "19",
              "19",
              "19",
              "19",
              "16"
            ],
            "tempsMinUpper": [
              "",
              "23",
              "22",
              "22",
              "23",
              "24",
              "24"
            ]
          }
        ],
        "timeDefines": [
          "2024-09-27T00:00:00+09:00",
          "2024-09-28T00:00:00+09:00",
          "2024-09-29T00:00:00+09:00",
          "2024-09-30T00:00:00+09:00",
          "2024-10-01T00:00:00+09:00",
          "2024-10-02T00:00:00+09:00",
          "2024-10-03T00:00:00+09:00"
        ]
      }
    ]
  }
]

この中から都道府県・エリアごとの1週間の天気コード[1].timeSeries.areas[].weatherCodesを取得してみます。

以下が外部APIからデータを取得してlogとして表示するWorkflowsになります。

wf-http.yml
main:
  steps:
    - init:
        assign:
          - prefs:
              100000: 群馬県
              110000: 埼玉県
              120000: 千葉県
              130000: 東京都
              140000: 神奈川県
    - loop_prefs:
        for:
          value: pref_code
          in: ${keys(prefs)}
          steps:
            - call_api:
                call: http.get
                args:
                  url: ${"https://www.jma.go.jp/bosai/forecast/data/forecast/" + pref_code + ".json"}
                result: result_api
            - loop_area:
                for:
                  value: v
                  in: ${result_api.body[1].timeSeries[0].areas}
                  steps:
                  - logging_area:
                      call: sys.log
                      args:
                        text: ${v.area.code + ":" + v.area.name}
                        severity: INFO
                  - logging_area_data:
                      call: sys.log
                      args:
                        text: ${v.weatherCodes}
                        severity: INFO
    - the_end:
        return: ${prefs}

いくつかStepがありますので解説します。
始めにinitステップで1週間の天気予報を取得する都道府県・エリアコードをMapで定義しています。
次にloop_prefsで定義した都道府県・エリアコードに対するHTTPエンドポイントにリクエストを行っています。
loop_prefsの中ではループごとにStepが有り始めに都道府県・エリアコードに対するHTTPエンドポイントにリクエストを行い、その結果から[1].timeSeries.areas[]を取得し、更にそれをloop_areaとしてループし最終的にほしいエリア名[1].timeSeries.areas[].area.nameと天気コード[1].timeSeries.areas[].weatherCodesを取得してログに出力しています。

これを可視化すると次のようなものになります。
workflow

ではこれをDeployして実行してみます。

$ gcloud workflows deploy wf-http --source=wf-http.yml --location asia-northeast1
$ gcloud workflows run wf-http --location asia-northeast1
argument: 'null'
createTime: '2024-09-29T12:23:49.895005423Z'
duration: 3.774371777s
endTime: '2024-09-29T12:23:53.669377200Z'
name: projects/{プロジェクトID}/locations/asia-northeast1/workflows/wf-http/executions/ded8d075-76f9-4338-85ed-eca954b968cd
result: '{"100000":"群馬県","110000":"埼玉県","120000":"千葉県","130000":"東京都","140000":"神奈川県"}'
startTime: '2024-09-29T12:23:49.895005423Z'
state: SUCCEEDED
status:
  currentSteps:
  - routine: main
    step: the_end
workflowRevisionId: 000016-c77

ではログを表示してみます。

wf-log

想定通りにエリア名と1週間の天気コードを取得できていることがわかります。

まとめ

GoogleCloudのWorkflowsで外部のAPIからデータを取得してそのレスポンスを扱ってみました。StepでHTTPリクエストを設定でき、レスポンスデータもJson型なら簡単に扱えるのでとても便利です。今回はエラーハンドルを行っていませんがレスポンスのステータスコードでエラーハンドルもできるのでかなり汎用性は高いと思いました。

最後まで読んで頂いてありがとうございました。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.